package collector.module;

import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import system.Execute;
import collector.core.CollectConstants;
import collector.core.TaskConstVO;
import collector.core.config.ConfigModule;
import collector.core.util.ScheduleUtil;
import collector.task.JobStateVO;

/**
 * <pre>
 * Class : collector.module.ModuleJob / ModuleJob.java
 * 	Define Class Object : 작업 실행을 위한 객체, 
 * 				작업 상태, 결과 등 작업의 공통 정보를 정의함. 
 * <br>
 * </pre>
 * @author ytjeong / apexcns,Inc.
 * @version 1.0
 * @see javadoc
 * @since 2012. 9. 18.
 */
public class ModuleJob implements Job
{
	private static Logger _log = LoggerFactory.getLogger(ModuleJob.class);
	private static final String _LogPrefixStr = CollectConstants.LOGGER_MODULE_NAME_JMC + CollectConstants.LOGGER_MODULE_NAME_AFTFIX;

	private ConfigModule configModule = ConfigModule.getConfig(ConfigModule.class);
	    
	/**
	 * <p>
	 * Empty constructor for job initialization
	 * </p>
	 * <p>
	 * Quartz requires a public empty constructor so that the
	 * scheduler can instantiate the class whenever it needs.
	 * </p>
	 */
	public ModuleJob() {
	}
	    
	public void execute(JobExecutionContext context) throws JobExecutionException {
        // This job simply prints out its job name and the
        // date and time that it is running
        JobKey jobKey = context.getJobDetail().getKey();
        
        Date cdate = new Date();

        _log.info(_LogPrefixStr + "----- Executing Job Task -------------------");
        
        // Grab and print passed parameters
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String jobIDs = dataMap.getString(CollectConstants.EXECUTION_JOBIDS);
        int reccount = 0;
        int prejobstate = 0;
        JobStateVO jsVo = (JobStateVO)dataMap.get(CollectConstants.EXECUTION_JOBSTATEVO);	// 작업 정보를 담을 객체 생성
        
        {// dataMap에 없거나 미정의된 경우 새로운 값으로 재 정의
	        if (jobIDs == null) {
	            _log.debug(_LogPrefixStr + "Get dataMap Value jobIDs=null, put jobIDs");
	            jobIDs = jobKey.getName();
	        }
	        try {
		        reccount = dataMap.getIntValue(CollectConstants.EXECUTION_RECCOUNT);
		        _log.debug(_LogPrefixStr + "Get dataMap Value reccount="+reccount);
	        } catch (Exception e) { _log.error(_LogPrefixStr + "Get dataMap Value reccount="+reccount + " :: " + e.getMessage(), e); }
	        try {
            	prejobstate = dataMap.getIntValue(CollectConstants.EXECUTION_PREJOBSTATE);
	        	_log.debug(_LogPrefixStr + "Get dataMap Value prejobstate="+prejobstate);
	        } catch (Exception e) { _log.error(_LogPrefixStr + "Get dataMap Value prejobstate="+prejobstate + " :: " + e.getMessage(), e); }
        	        
	        if (jsVo == null) {
	            _log.debug(_LogPrefixStr + "Get dataMap Value jsVo=null, create new"); 
	            jsVo = new JobStateVO(jobIDs);
	        }
        }
		
		for (TaskConstVO tcvo : configModule.getModuleTaskList()) {
		    if (jobIDs.equals(tcvo.getTaskName())) {
				int pastValue = -1; // default , case TX_LOGGING_01 then 2
				if ("TX_LOGGING_01".equals(jobIDs)) pastValue = -2;
	
		        _log.info(_LogPrefixStr + "Job: " + jobKey + " scheduled at " + tcvo.getScheduleDateStr() + "\n"
		        			+ "  job IDs is " + jobIDs + " " + " executing at " + cdate + "\n"
		        			+ "  execution reccount is " + reccount + ", " 
		        			+ "  execution prejobstate is " + prejobstate + " ");
		        _log.info(_LogPrefixStr + "----- Ready to Excute Task [" + jobIDs + "] for ConfigTask -------------------");
				_log.debug(_LogPrefixStr + "Excute Task TaskConstVO=" + tcvo);
				
				//oDate = getScheduleCurrentTime(pTime, pastValue);
				Execute exc = new Execute();
				String ScheduleToTime = ScheduleUtil.convScheduleCurrentTime(tcvo.getScheduleDateStr(), tcvo.getDurationType(), tcvo.getDurationValue(), pastValue);

				_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
				_log.info(_LogPrefixStr + " End 조회시각 :: " + ScheduleToTime);	// DAY의 경우 pastValue 가 0보다 적어야 이전일로 처리됨. - ByJeong
				_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
				
				// String[] params = new String[]{모듈 작업명, Duration 주기, End 조회시각, Duration 주기 값}
				String[] params = new String[]{jobIDs, tcvo.getDurationType(), ScheduleToTime, tcvo.getDurationValue() + ""};
				try {
				    JobStateVO tmpjsVo = exc.doMain(params, true);
				    jsVo.updateJobStateVo(tmpjsVo); // 정보 갱신
				    
					_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
					_log.info(_LogPrefixStr + " Task result :: " + jsVo.toStringDisplay());
					_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
				} catch (Exception e) {
		            JobExecutionException e2 = new JobExecutionException(e);
			               
	                // fix denominator so the next time this job run
	                // it won't fail again
					dataMap.put(CollectConstants.EXECUTION_JOBIDS, jobIDs);
					dataMap.put(CollectConstants.EXECUTION_RECCOUNT, reccount);
					dataMap.put(CollectConstants.EXECUTION_PREJOBSTATE, prejobstate);
					dataMap.put(CollectConstants.EXECUTION_JOBSTATEVO, jsVo);
			                
	                // this job will refire immediately
	                e2.setRefireImmediately(true);
	                throw e2;
				}
		        // increment the count and store it back into the 
		        // job map so that job state can be properly maintained
				reccount++;
				prejobstate = jsVo.getJobResultCode();
		    }
		}
		dataMap.put(CollectConstants.EXECUTION_JOBIDS, jobIDs);
		dataMap.put(CollectConstants.EXECUTION_RECCOUNT, reccount);
		dataMap.put(CollectConstants.EXECUTION_PREJOBSTATE, prejobstate);
		dataMap.put(CollectConstants.EXECUTION_JOBSTATEVO, jsVo);
		// 코드 수정 complete log [By Lee 2012.09.21]
		_log.info(_LogPrefixStr + "----- Complete to Excute Task [" + jobIDs + "] -------------------");
	}
}
